#ifndef MEOW_TRANSLATOR_H_INCLUDED
#define MEOW_TRANSLATOR_H_INCLUDED
#include <string>
#include <vector>
#define MT_MEOW L"喵"
#define MT_MI L"咪"
#define MT_SPLIT L"|"
#define MT_IS_VALID_STR(s) (s == MT_MEOW || s == MT_MI || s == MT_SPLIT)

#define MT_STATUS int
#define MT_SUCCESS 0
#define MT_ERROR -1
#define MT_EMPTY_STR -2

const std::wstring empty_wstr = L"";

namespace loveaabb
{
    static size_t clear_invalid_str(std::wstring& str)
    {
        std::wstring buf, curss;
        size_t ret = 0;

        for (size_t i = 0; i < str.size(); i++)
        {
            curss = str.substr(i, 1);
            if (MT_IS_VALID_STR(curss))
            {
                buf += curss;
                ret++;
            }
        }

        str = buf;
        return ret;
    }

    size_t size_without_spaces(std::wstring const& str)
    {
        size_t spc = 0;
        std::wstring curss;

        for (size_t i = 0; i < str.size(); i++)
        {
            curss = str.substr(i, 1);
            if (curss == L" " || curss == L"\n")
            {
                spc++;
            }
        }

        return (str.size() - spc);
    }

    MT_STATUS meow2human(std::wstring& target, std::wstring const& src, size_t& validn)
    {
        wchar_t curc;
        int meown;
        std::wstring buf = src, curstr;

        target.clear();
        validn = clear_invalid_str(buf);
        buf = buf + MT_SPLIT + MT_MI + MT_SPLIT;

        if (src.size() <= 0)
        {
            return MT_EMPTY_STR;
        }

        curc = 0;
        meown = -1;
        for (size_t i = 0; i < buf.size(); i++)
        {
            curstr = buf.substr(i, 1);
            if (curstr == MT_MEOW)
            {
                meown++;
            }
            else if (curstr == MT_SPLIT)
            {
                if (meown < 0 || meown > 7 || (curc * 8 + meown < curc))
                {
                    target.clear();
                    return MT_ERROR;
                }
                curc = curc * 8 + meown;
                meown = -1;
            }
            else if (curstr == MT_MI)
            {
                if (i == 0 || i == buf.size() - 1 || buf.substr(i-1, 1) != MT_SPLIT || buf.substr(i+1, 1) != MT_SPLIT)
                {
                    target.clear();
                    return MT_ERROR;
                }
                target += curc;
                meown = 0;
                curc = 0;
            }
        }

        return MT_SUCCESS;
    }

    MT_STATUS meow2human(std::wstring& target, std::wstring const& src)
    {
        size_t validn;
        return meow2human(target, src, validn);
    }

    MT_STATUS human2meow(std::wstring& target, std::wstring const& src)
    {
        wchar_t curc;
        int j;

        if (src.size() <= 0)
        {
            return MT_EMPTY_STR;
        }

        for (size_t i = 0; i < src.size(); i++)
        {
            curc = src[i];
            for (j = 0; curc >> (j + 3) != 0; j += 3);

            while (j >= 0)
            {
                for (int k = 0; k < ((curc >> j) % 8 + 1); k++)
                {
                    target += MT_MEOW;
                }

                if (!(i == src.size() - 1 && j == 0)) target = target + L" " + MT_SPLIT + L" ";

                j -= 3;
            }

            if (i != src.size() - 1) target = target + MT_MI + L" " + MT_SPLIT + L" ";
        }

        return MT_SUCCESS;
    }
}

#endif // MEOW_TRANSLATOR_H_INCLUDED
